import React, {useRef, useState, forwardRef, useCallback, memo} from 'react';

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faDungeon, faDoorOpen, faDoorClosed, faArrowUp, faArrowDown, faPlus} from '@fortawesome/free-solid-svg-icons'

// declaring component as pure functional

const AdditiveElem = memo(({data, index, moveBack, moveFore}) => {

  const [, refresh] = useState();
  
  const addToList = () => {
    data[index].lines.push(data[index].lines.length);
    refresh({});
  }

  const back = (e) => {
    moveBack(index);
  }

  const fore = (e) => {
    moveFore(index);
  }

  return <div className='additive-elem'>
    <div>Index {index.toString().padEnd(5, ' ')}</div>
    <div>Line {data[index].line.toString().padEnd(5, ' ')}</div>
    <div>Code {data[index].code.toString().padEnd(5, ' ')}</div>
    <div>{data[index].lines.map((e, i) => <div key={i}>Elem {e}</div>)}</div>
    <div style={{display: 'flex'}}>
      <FontAwesomeIcon className='button' icon={faPlus} onClick={addToList}/>
      <FontAwesomeIcon className='button' icon={faArrowUp} onClick={back}/>
      <FontAwesomeIcon className='button' icon={faArrowDown} onClick={fore}/>
    </div>
  </div>
})



const makeRow = ({enter, leave}) => {
  const res = forwardRef(({index, data, style, refreshItem}, ref) => {

    // **style of outermost level**
    // 
    // position:absolute is manadatory, so that to anchor over
    // the closest parent DOM. and always merge the bound into
    // the inline style of actual DOM, for proper position and
    // height.

    const outerStyle = {
      width:'100%',
      ...style
    }

    const innerStyle = {
      width: '100%',
      display:'flex',
      alignItems: 'center',
      padding: '5px',
      // borderBottom:'1px solid black',
      whiteSpace: 'pre',
      fontFamily: '"TheSansMono", "Droid Sans Mono", Menlo, Consolas, monospace',
      letterSpacing: '-0.05rem',
      backgroundColor: index % 2 ? 'rgb(240, 240, 240)' : 'white',
      boxSizing:'border-box',
    }


    // YOU WANT THESE FUNCTIONS TO BE UPDATE FOR EACH RENDER
    // THUS NO USE_CALLBACK.
    const moveBack = (index) => {
      [data[index], data[index - 1]] = [data[index - 1], data[index]];
      refreshItem(index);
    }

    const moveFore = (index) => {
      [data[index], data[index + 1]] = [data[index + 1], data[index]];
      refreshItem(index);
    };

    const handleNav = useCallback((e) => {
      e.stopPropagation();
      e.preventDefault();
      const navFunc = enter || leave || (() => {});
      navFunc(data[index]);
      // refreshItem(0);
    }, []);

    const icon = enter
    ? <FontAwesomeIcon icon={faDungeon} />
    : leave
    ? <FontAwesomeIcon icon={faDoorClosed} />
    : ''
    

    return <div style={outerStyle}>
      <div style={innerStyle} ref={ref}>
        <button className="button" onClick={handleNav}>{icon}</button>
        <AdditiveElem {...{data, index, moveBack, moveFore}}/>
      </div>
    </div>
  });

  return res;
}

export default makeRow;